package com.frame.common;

import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;

/**
 * <p>Title: xml操作</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 * <p>Company: </p>
 * @author ccs
 * @version 1.0
 */

final public class Xml
{
   static public class ArrayNodeList implements NodeList
   {
      private List nodes;

      public ArrayNodeList(List nodes)
      {
         this.nodes = nodes;
      }

      public Node item(int index)
      {
         return(Node)nodes.get(index);
      }

      public int getLength()
      {
         return nodes.size();
      }
   }

   private Xml()
   {
   }

   static public Document createDocument() throws Exception
   {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document document = builder.newDocument();
      return document;
   }

   static public Document createDocument(byte[] data) throws Exception
   {
      return createDocument(new ByteArrayInputStream(data));
   }

   static public Document createDocument(String path) throws Exception
   {
      return createDocument(new File(path));
   }

   static public Document createDocument(File file) throws Exception
   {
      InputStream in = null;
      try
      {
         in = new FileInputStream(file);
         return createDocument(in);
      }
      finally
      {
         if(in != null)
         {
            try
            {
               in.close();
            }
            catch(Throwable ex)
            {
            }
         }
      }
   }

   static public Document createDocument(InputStream in) throws Exception
   {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document document = builder.parse(in);

      return document;
   }
   static public Document createDocument(InputStream in,String charname) throws Exception
   {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      InputSource inputSource=new InputSource(new InputStreamReader(in,charname));
      Document document = builder.parse(inputSource);
      return document;
   }

   /**
    * 保存xml文档
    * @param out
    * @param document
    * @throws FlowEngineException
    */
   static public void saveDocument(OutputStream out,Document document,
                                   String charset) throws Exception
   {
      TransformerFactory tFactory = TransformerFactory.newInstance();
      Transformer transformer = tFactory.newTransformer();
      DOMSource source = new DOMSource(document);
      StreamResult result = new StreamResult(out);
      if(charset != null)
         transformer.setOutputProperty(OutputKeys.ENCODING,charset);
      transformer.transform(source,result);
   }

   /**
    * 保存xml
    * @param document
    * @return
    * @throws FlowEngineException
    */
   static public byte[] saveDocument(Document document,String charset) throws
           Exception
   {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      saveDocument(out,document,charset);
      return out.toByteArray();
   }

   static public Element getChildElement(Element element,String elementName)
   {
      NodeList nodeList = element.getChildNodes();
      int n = nodeList.getLength();
      for(int i = 0; i < n; i++)
      {
         Node node = nodeList.item(i);
         if(node instanceof Element && elementName.equals(node.getNodeName()))
            return(Element)node;
      }
      return null;
   }

   static public String getElementValue(Element element)
   {
      NodeList nodeList = element.getChildNodes();
      int n = nodeList.getLength();
      String value = null;
      for(int i = 0; i < n; i++)
      {
         Node node = nodeList.item(i);
         if(node.getNodeType() == Node.CDATA_SECTION_NODE)
            return node.getNodeValue();
         if(node.getNodeType() == Node.TEXT_NODE && value == null)
            value = node.getNodeValue();
      }
      return value;
   }

   static public String getElementValue(Element element,String elementName)
   {
      NodeList nodeList = element.getChildNodes();
      int n = nodeList.getLength();
      for(int i = 0; i < n; i++)
      {
         Node node = nodeList.item(i);
         if(node instanceof Element && elementName.equals(node.getNodeName()))
            return getElementValue((Element)node);
      }
      return null;
   }

   static public String parseXmlEncoding(InputStream in) throws IOException
   {
      BufferedReader reader = new BufferedReader(new InputStreamReader(in));
      String line = reader.readLine();
      if(!line.startsWith("<?xml"))
         return null;

      line = line.substring(6);

      Map map = new HashMap();
      boolean b = false;
      do
      {
         String[] ss = line.split("\"");
         for(int i = 0; i < ss.length; i++)
         {
            String s = ss[i];

            if(i % 2 == 0)
            {
               if(s.trim().startsWith("encoding"))
                  b = true;

               if(s.trim().startsWith("?>"))
                  return null;
            }
            else
            {
               if(b)
                  return s;
            }
         }
      }
      while((line = reader.readLine()) != null);

      return null;
   }

   static public NodeList getChildNodesByName(Element element,String name)
   {
      NodeList nodes = element.getChildNodes();
      int n = nodes.getLength();
      List list = new ArrayList(n / 2 + 1);
      for(int i = 0; i < n; i++)
      {
         Node node = nodes.item(i);
         if(node.getNodeName().equals(name))
            list.add(node);
      }

      return new ArrayNodeList(list);
   }

   static public void parseXml(InputStream in,DefaultHandler handler) throws
           Exception
   {
      SAXParserFactory factory = SAXParserFactory.newInstance();
      SAXParser parser = factory.newSAXParser();

      parser.parse(in,handler);
   }

   static public void parseXml(File file,DefaultHandler handler) throws
           Exception
   {
      InputStream in = null;
      try
      {
         in = new FileInputStream(file);
         parseXml(in,handler);
      }
      finally
      {
         if(in != null)
         {
            try
            {
               in.close();
            }
            catch(Throwable ex)
            {
            }
         }
      }
   }

   static public void parseXml(String path,DefaultHandler handler) throws
           Exception
   {
      parseXml(new File(path),handler);
   }
}